# encoding=utf-8
# -------------------------------------------------------------------------------
# Name:        module1
# Purpose:
#
# Author:
#
# Created:     16/05/2022
# Copyright:   (c)  2022
# Licence:     <your licence>
# -------------------------------------------------------------------------------
import requests
import os
import zipfile
import re
import sys
import json
import random
from functools import partial
from PIL import Image, ImageDraw, ImageFont, ImageTk, ImageGrab
import json
import io
import logging
import mimetypes
import time
import threading
from socket import *
from bottle import route, run, template, static_file, response, request, abort
import hashlib
# reload(sys)
# sys.setdefaultencoding('gb2312')


def download_zip(url, path):
    rsp = requests.get(url, stream=True)
    with open(path, 'wb') as of:
        for chunk in rsp.iter_content(chunk_size=1024):
            if chunk:
                of.write(chunk)


def extract_zip(zip_path, path):
    zip = zipfile.ZipFile(zip_path)
    zip.extractall(path)
    zip.close()
    os.remove(zip_path)


of = None


def get_cron(name, txt, path):
    global of
    regx = r'[\d\*]{1,2}(\s[\*\d,-/]+){4}'
    for i in range(2):
        m = re.search(regx, txt or '')
        if not m:
            if i == 0:
                txt = get_old_cron(name)
                continue
            print(name)
            return
    if not of:
        of = myopen(os.path.join(path, 'cron.sh'), 'w', encoding='utf8')
    of.write('%s\t\tbash ajd.sh %s\n' %
             (m.group(), name.replace('.ts', '.js')))
    return 1


cron_txt = ''


def get_old_cron(name):
    path = r'\\192.168.68.2\usb\scripts\docker\merged_list_file.sh'
    if not os.path.exists(path):
        return
    global cron_txt
    if not cron_txt:
        with myopen(path, 'r', encoding='utf8') as of:
            cron_txt = of.read()
    js = name.replace('.ts', '.js')
    js = '/%s' % js
    js = js.decode('gb2312')
    if js not in cron_txt:
        return
    pos = cron_txt.find(js)
    pos2 = cron_txt[0:pos].rfind('\n')
    txt = cron_txt[pos2:pos]
    return txt


def main():
    path = r'd:\code\jd_helloworld'
    if not os.path.exists(path):
        os.makedirs(path)
    url = 'https://github.com/YUXIKUN/JDHelloWorld_jd_scripts/archive/refs/heads/main.zip'
    zip_path = os.path.join(path, os.path.basename(url))
# download_zip(url, zip_path)
# extract_zip(zip_path, path)

    for s in os.listdir(path):
        p = os.path.join(path, s)
        if os.path.isdir(p):
            path = p
            break

    lst = os.listdir(path)
    for s in lst:
        if s.endswith('.js') or s.endswith('.ts'):
            p = os.path.join(path, s)
            with myopen(p, 'r', encoding='utf8') as of:
                txt = of.read()
                get_cron(s, txt, path)
    of = globals()['of']
    if of:
        of.close()


def myopen(*args, **kargs):
    if sys.version_info.major == 2:
        import codecs
        return codecs.open(*args, **kargs)
    else:
        return open(*args, **kargs)


id2node = {}


def loop(draw, node, nodes, colors, nodeVisiter=None):
    nodes.append(node)
    node['aid'] = len(nodes)
    id2node[len(nodes)] = node
    a = node.get('boundsInfo').get('left')
    b = node.get('boundsInfo').get('top')

    c = node.get('boundsInfo').get('right')
    d = node.get('boundsInfo').get('bottom')

    text = node.get('content')
    if text:
        if '消耗8000爆竹' in text:
            t = 1
        font_en = globals().get('font_en', 0)
        if not font_en:
            font_en = ImageFont.truetype(r'C:\Windows\Fonts\msyhl.ttc', 20)
            globals()['font_en'] = font_en
        if hasattr(draw, 'text'):
            draw.text((a, b), text, font=font_en, fill='green')
        else:
            draw.draw_text(text, (a, b), font=font_en, color='green')

    valid = True
    if valid:
        lst = [a, b, c, d]
        try:
            if hasattr(draw, 'rectangle'):
                draw.rectangle(lst, outline=random.choice(colors))
            else:
                draw.draw_rectangle(
                    (a, b), (c, d), line_color=random.choice(colors))
        except:
            print(lst)
    else:
        print(len(nodes))
    if nodeVisiter:
        nodeVisiter(node)
    for n in node.get('childs', []):
        n['parent'] = node.get('aid')
        loop(draw, n, nodes, colors, nodeVisiter)


def test_json_image(name, loopFunc=loop, graph=None, pic=None, save=''):
    if os.path.exists(name):
        path = name
        pic = pic or path.replace('.json', '.png')
    else:
        sdir = os.path.dirname(__file__)
        path = os.path.join(sdir, r'auto_gui\autojs\%s.json' % name)
        pic = os.path.join(sdir, r'auto_gui\autojs\%s.jpg' % name)
    obj = {}
    with open(path, 'r', encoding='utf8') as of:
        obj = json.load(of)
    w, h = 0, 0
    bottom = 'bottom'
    left = 'left'
    right = 'right'
    top = 'top'
    if obj:
        w = obj[0].get('boundsInfo').get(right)+1
        h = obj[0].get('boundsInfo').get(bottom)+1
    if not graph:
        if os.path.exists(pic):
            image = Image.open(pic, 'r')
        else:
            image = Image.new('RGB', (w, h), 'white')
        draw = ImageDraw.Draw(image)
        draw.image = image
    else:
        draw = graph

    r, g, b = 0, 0, 0
    sub = 50
    nodes = []
    for n in obj:
        loopFunc(draw, n, nodes, ['red', 'green',
                 'blue', 'black', 'Pink', 'Yellow'])
    if save:
        image.save(save)
    globals()['nodes'] = nodes
    return nodes, draw


def get_node_postion(node):
    bottom = 'bottom'
    left = 'left'
    right = 'right'
    top = 'top'
    a = node.get('boundsInfo').get(left)
    b = node.get('boundsInfo').get(top)

    c = node.get('boundsInfo').get(right)
    d = node.get('boundsInfo').get(bottom)
    return a, b, c, d


def get_node_in_pos(x, y, nodes):
    lst = []
    for node in nodes:
        a, b, c, d = get_node_postion(node)

        if (x > a and x < c) and (y > b and y < d):
            w, h = c-a, d-b
            node['area'] = w*h
            lst.append(node)
    lst.sort(key=lambda x: x['area'])
    return lst


def get_node_path(txt, node2):
    for node in nodes:
        t = node.get('content')
        if t == txt:
            break
    path1 = []
    path2 = []
    while node:
        path1.append(node.get('aid', 0))
        node = id2node.get(node.get('parent', 0))
    while node2:
        idx = node2.get('aid', 0)
        if idx in path1:
            print(json.dumps(node2))
            t = ''
            for n in path1[0:path1.index(idx)]:
                t += '.parent()'

            path2.reverse()
            for n in path2:
                node = id2node.get(n)
                t += '.child(%s)' % node.get('index', -1)
            return t
        path2.append(idx)
        node2 = id2node.get(node2.get('parent', 0))


def test_pythonet():
    import clr
    path = r'D:\code\sharp\XX1UI\NodeViewerLib\bin\Debug'
    if not path in sys.path:
        sys.path.append(path)
    clr.AddReference('System.Windows.Forms')
    clr.AddReference('System.Drawing')
    clr.AddReference('NodeViewerLib')

    import System.Windows.Forms as Forms
    import System.Drawing
    import NodeViewerLib

    class MyForm(Forms.Form):
        def __init__(self):
            self.userControl11 = NodeViewerLib.UserControl1()
            self.SuspendLayout()
            self.userControl11.Anchor = (
                ((((Forms.AnchorStyles.Top | Forms.AnchorStyles.Bottom) | Forms.AnchorStyles.Left) | Forms.AnchorStyles.Right)))
            self.userControl11.Location = System.Drawing.Point(-1, 0)
            self.userControl11.Name = "userControl11"
            self.userControl11.Size = System.Drawing.Size(1028, 676)
            self.userControl11.TabIndex = 0

            self.AutoScaleDimensions = System.Drawing.SizeF(6.0, 12.0)
            self.AutoScaleMode = Forms.AutoScaleMode.Font
            self.ClientSize = System.Drawing.Size(1030, 677)
            self.Controls.Add(self.userControl11)
            self.Name = "MainForm"
            self.Text = "NodeViewer"
            self.ResumeLayout(False)

    Forms.Application.EnableVisualStyles()
    Forms.Application.SetCompatibleTextRenderingDefault(False)
    Forms.Application.Run(MyForm())


class NodeVisitor:
    def __init__(self, treedata):
        self.treedata = treedata

    def getAttr(self, node):
        if not node:
            return ''
        if not hasattr(node, 'get'):
            a = 1
        ids = node.get('id') or ''
        if ids:
            ids = ids.split('/')[-1]
        clsname = node.get('className')
        content = node.get('content')
        aid = node.get('aid')
        return aid, clsname, [ids, content]

    def __call__(self, node):
        parent = node.get('parent', 0)
        if not parent:
            parent = ''
        aid, clsname, values = self.getAttr(node)
        self.treedata.insert(parent, aid, clsname, values=values)


def display_node(node):
    mp = {}
    for k, v in node.items():
        if isinstance(v, dict):
            continue
        mp[k] = v
    mp['postion'] = [x for x in get_node_postion(node)]
    return json.dumps(mp, indent=2, ensure_ascii=False)


def show_image(graph, image):
    w, h = image.size
    buf = io.BytesIO()
    image.save(buf, format="PNG")
    graph.draw_image(data=buf.getvalue(), location=(0, h))


def AutojsElementSelect():
    import PySimpleGUI as sg
    jsonFile = sg.popup_get_file('JSON file to open')
    if not jsonFile:
        sg.popup_cancel('Cancelling')
        raise SystemExit()
    treedata = sg.TreeData()
    w, h = 1081, 2161
    scale = 0.5
    loop2 = partial(loop, nodeVisiter=NodeVisitor(treedata))
    nodes, image = test_json_image(jsonFile, loop2)
    winW, winH = ImageGrab.grab().size
    if (hasattr(image, 'image')):
        w, h = image.image.size
        w, h = w*scale, h*scale
    graph = sg.Graph(canvas_size=(w, h),
                     graph_bottom_left=(0, 0),
                     graph_top_right=(w, h),
                     change_submits=True,
                     enable_events=True,
                     key='graph')
    left = [
        [sg.Tree(data=treedata,
                 headings=['ID', 'Content'],
                 auto_size_columns=True,
                 select_mode=sg.TABLE_SELECT_MODE_EXTENDED,
                 num_rows=40,
                 col0_width=100,
                 key='-TREE-',
                 vertical_scroll_only=False,
                 show_expanded=True,
                 enable_events=True,
                 expand_x=True,
                 expand_y=True,
                 ),],
        [
            sg.Multiline(size=(100, 10), autoscroll=True, key='text',
                         auto_size_text=True, expand_x=1, expand_y=1)
        ]
    ]
    right = [[graph]]
    colw, colh = 800, 800
    layout = [
        [sg.Column(left, size=(colw, colh), scrollable=True),
         sg.VSeperator(),
         sg.Column(right, size=(600, colh), scrollable=True)
         ]
    ]
    window = sg.Window('Tree Element Test', layout,
                       resizable=True, finalize=True)
    if (hasattr(image, 'image')):
        image.image.thumbnail((w, h))
        path = jsonFile + '.png'
        image.image.save(path, format="PNG")

        show_image(graph, image.image)
        window.refresh()
    while 1:
        event, values = window.read()
        if event in (sg.WIN_CLOSED, 'Cancel'):
            break
        # print(event, values)
        if event == 'graph':
            x, y = values[event]
            lst = get_node_in_pos(x, y, nodes)
        elif event == '-TREE-':
            aid = values[event][0]
            node = id2node[aid]
            a, b, c, d = [x*scale for x in get_node_postion(node)]
            window['text'].update(display_node(node))
            if (hasattr(image, 'image')):
                image.rectangle([a, b, c, d], outline='red')
                show_image(graph, image.image)
            else:
                graph.draw_rectangle(
                    (b, a), (d, c), line_color='red', line_width=5)


class HttpConf:
    currentPath = os.path.dirname(os.path.abspath(__file__))
    uploadDir = os.path.join(currentPath, 'upload')
    if not os.path.exists(uploadDir):
        os.makedirs(uploadDir)
    jsonFile = ''
    imageFile = ''
    imageFileDisplay = ''
    @classmethod
    def cleanFile(cls):
        for path in [cls.imageFile, cls.imageFileDisplay]:
            if path and os.path.exists(path):
                os.remove(path)
        cls.imageFile = ''
        cls.imageFileDisplay = ''
    @classmethod
    def makeFileName(cls, name, fileName=None):
        if name == 'jsonFile':
            cls.jsonFile = os.path.join(HttpConf.uploadDir, 'uiobjects.json')
        elif name == 'imageFile':
            ext = os.path.splitext(fileName)[-1]
            cls.imageFile = os.path.join(HttpConf.uploadDir, 'uiobjects_pic_from_user'+ext)
        else:
            cls.imageFileDisplay = os.path.join(HttpConf.uploadDir, 'uiobjects_pic_to_user.png')

@route('/')
def index():
    logging.info('index')
    path = HttpConf.currentPath
    return static_file('element.html', path)

@route('/json/<name>', 'POST')
def post_data(name):
    response.set_header('Content-type', 'application/json')
    result = {
        'status': 200,
        'message':'ok',
        'jsonUrl':'/json/uiobjects',
        'imageUrl':'/json/image?t=%d'%time.time()
    }
    if name == 'jdlayout':
        for k,v in request.files.items():
            logging.info(v.filename)
            if v.filename.endswith('.json'):
                HttpConf.cleanFile()
                HttpConf.makeFileName('jsonFile')
                v.save(HttpConf.jsonFile, overwrite=True)
            else:
                typ = mimetypes.guess_type(v.filename)[0]
                if not typ or not typ.startswith('image/'):
                    response.status = 500
                    result['status'] = response.status_code
                    result['message']='不可识别的文件类型.'+v.filename
                    break
                HttpConf.makeFileName('imageFile', v.filename)
                if not HttpConf.imageFile:
                    response.status = 500
                    result['status'] = response.status_code
                    result['message']='文件保存失败.'
                    break
                v.save(HttpConf.imageFile, overwrite=True)
                logging.info(HttpConf.imageFile)
    return json.dumps(result)

@route('/json/<name:re:.*>', 'GET')
def get_data(name):
    if name == 'uiobjects':
        response.set_header('Content-type', 'application/json')
        HttpConf.makeFileName('imageFileDisplay')
        thrd = threading.Thread(
            target=test_json_image,
            args=(HttpConf.jsonFile,),
            kwargs={'pic':HttpConf.imageFile, 'save':HttpConf.imageFileDisplay})
        thrd.start()
        thrd.join()
        return static_file(os.path.basename(HttpConf.jsonFile), HttpConf.uploadDir)
    elif name == 'image':
        i = 0
        logging.info(name)
        while i < 10:
            i+=1
            if HttpConf.imageFile:
                break
            time.sleep(0.5)
        logging.info(HttpConf.imageFileDisplay)
        im = os.path.basename(HttpConf.imageFileDisplay)
        a = os.path.exists(HttpConf.imageFileDisplay)
        return static_file(im, HttpConf.uploadDir)
    elif name == 'point':
        pass

def readUpdate(query):
    path = os.path.join(os.path.dirname(__file__), 'switch.json')
    if not os.path.exists(path):
        of = open(path, 'wb')
        of.close()
    with open(path, 'r', encoding='utf8') as of:
        txt = of.read()
    m = query.get('m','')
    if m:
        lst = json.loads(txt) if txt else []
        if m not in lst:
            lst.append(m)
    else:
        lst = []
    with open(path, 'w', encoding='utf8') as of:
        txt = json.dumps(lst)
        of.write(txt)
    return lst

@route('/switch/<optype:re:.*>', 'GET')
def lemesh_switch(optype):
    lst = readUpdate(request.query)
    if optype == 'open':
        device_param = "[{'did':'1060617213','value':True,'siid':2,'piid':1}]"
    elif optype == 'close':
        if len(lst) != 2:
            return 'wait second'
        device_param = "[{'did':'1060617213','value':False,'siid':2,'piid':1}]"
    device_gate_ip = '192.168.68.111'
    device_gate_token = ''
    exe = '/opt/pykonkeio/bin/miiocli'
    cmd = f'''{exe} device --ip {device_gate_ip} --token {device_gate_token} raw_command set_properties "{device_param}"'''
    log = os.path.join(os.path.dirname(__file__), 'miiocli.log')
    with os.popen(cmd, 'r') as of:
        ret = of.read().replace('\n',' ')
    with open(log, 'a', encoding='utf8') as of:
        of.write(time.strftime('%Y%m%d %H:%M:%S'))
        of.write(' ')
        of.write(ret)
        of.write('\n')
    return json.dumps({'result':ret})

def runBottle():
    logger = logging.getLogger()
    logname = 'jd_helloworld.log'
    port = 8080
    debug = 0
    if debug:
        logname = 'jd_helloworld2.log'
        port = 8081
    logger.setLevel(logging.DEBUG)
    logCount = 5
    logsize = 1024*1024*5

    #hdlr = logging.handlers.RotatingFileHandler(logname, 'w', logsize, logCount)
    hdlr = logging.FileHandler(logname, 'a', 'utf8')
    formater = logging.Formatter('%(asctime)s T%(thread)5d %(levelname)-8s %(message)s')
    hdlr.setFormatter(formater)
    logger.addHandler(hdlr)
    hdlr = logging.StreamHandler(sys.stdout)
    hdlr.setFormatter(formater)
    logger.addHandler(hdlr)
    server = 'wsgiref' or 'flup'
    run(host='0.0.0.0', port=386, reloader=True, server=server)

def convert2MD():
    txt = ''''''
    t = ''
    for s in txt.splitlines():
        m = re.search(r'(\d+)\.mp4', s)
        # t += '三体[%s](%s)\n'%(m.groups()[0],s)
        t+= '三体[%s]<video src="%s" controls="controls" width="500" height="300">您的浏览器不支持播放该视频！</video><br/>\n'%(m.groups()[0],s)
    print(t)
    sys.exit(0)

def loop_ftp(ftp=None, path='/mp4'):
    if not ftp:
        import ftplib
        ftp = ftplib.FTP('43.228.77.179', 'anonymous', 'anonymous')
    dir_lst = []
    file_lst = []
    for a in ftp.mlsd(path):
        if a[1].get('type') == 'dir':
            dir_lst.append(a[0])
        else:
            file_lst.append(a[0])
    if not dir_lst and len(file_lst) == 100:
        print(path)
    for a in dir_lst:
        loop_ftp(ftp, f'{path}/{a}')

def udp_server():
    # Create a UDP socket
    # Notice the use of SOCK_DGRAM for UDP packets
    serverSocket = socket(AF_INET, SOCK_DGRAM)

    # Assign IP address and port number to socket
    serverSocket.bind(('', 21115))

    while True:
        # Generate random number in the range of 0 to 10
        #rand = random.randint(0, 10)

        # Receive the client packet along with the address it is coming from
        message, address = serverSocket.recvfrom(1024)

        # Capitalize the message from the client
        message = message.upper()

        # If rand is less is than 4, we consider the packet lost and do notrespond
        #if rand < 4:
        #    continue

        # Otherwise, the server responds
        serverSocket.sendto(message, address)

def test_kimi():
    path = r'D:\code\VideoAudioManager\newRoute-yase.png'
    authorization = 'Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyLWNlbnRlciIsImV4cCI6MTc0NTQ5NzI4MywiaWF0IjoxNzM3NzIxMjgzLCJqdGkiOiJjdTlvYmdxaHJhMGJ0dmhwa3Q3MCIsInR5cCI6ImFjY2VzcyIsImFwcF9pZCI6ImtpbWkiLCJzdWIiOiJjdTMxdm90M3Y4OXZrbWQzdWRuMCIsInNwYWNlX2lkIjoiY3UzMXZvdDN2ODl2a21kM3VkbWciLCJhYnN0cmFjdF91c2VyX2lkIjoiY3UzMXZvdDN2ODl2a21kM3VkbTAiLCJyb2xlcyI6WyJ2aWRlb19nZW5fYWNjZXNzIl0sInNzaWQiOiIxNzMwNDgxNzY4NTQyOTQ1NTIxIiwiZGV2aWNlX2lkIjoiNzQwMjk4OTkyNDEzNzUxMTQyNSJ9.Hp0cAgnMLdzL6EcfVLG6AmfhszBewLLoKjtLIidHFRdDAxvFes50o0BMXXebWW8HCgxTube7bVOyEXRIeQh4EQ'
    cookie='lang=zh-CN; kimi-auth=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyLWNlbnRlciIsImV4cCI6MTc0NTQ5NzI4MywiaWF0IjoxNzM3NzIxMjgzLCJqdGkiOiJjdTlvYmdxaHJhMGJ0dmhwa3Q3MCIsInR5cCI6ImFjY2VzcyIsImFwcF9pZCI6ImtpbWkiLCJzdWIiOiJjdTMxdm90M3Y4OXZrbWQzdWRuMCIsInNwYWNlX2lkIjoiY3UzMXZvdDN2ODl2a21kM3VkbWciLCJhYnN0cmFjdF91c2VyX2lkIjoiY3UzMXZvdDN2ODl2a21kM3VkbTAiLCJyb2xlcyI6WyJ2aWRlb19nZW5fYWNjZXNzIl0sInNzaWQiOiIxNzMwNDgxNzY4NTQyOTQ1NTIxIiwiZGV2aWNlX2lkIjoiNzQwMjk4OTkyNDEzNzUxMTQyNSJ9.Hp0cAgnMLdzL6EcfVLG6AmfhszBewLLoKjtLIidHFRdDAxvFes50o0BMXXebWW8HCgxTube7bVOyEXRIeQh4EQ'
    url = 'https://kimi.moonshot.cn/api/pre-sign-url'
    data = {
      "name": os.path.basename(path),
      "action": "image"
    }
    headers = {
        "authorization": authorization,
        "content-type": 'application/json',
        'referer': 'https://kimi.moonshot.cn/',
        'cookie': cookie
    }
    s3obj = {'url': 'https://prod-chat-kimi-tos.moonshot.cn/prod-chat-kimi/kfs/1/2/2025-01-24/cu9p8tdf4398vu0atm9g?X-Tos-Algorithm=TOS4-HMAC-SHA256&X-Tos-Credential=AKLTYTJlNjgwMjY2ZDBkNDFiYmI5YWNiZDBlZmFmYjIzZTA%2F20250124%2Fcn-beijing%2Ftos%2Frequest&X-Tos-Date=20250124T132405Z&X-Tos-Expires=3600&X-Tos-Signature=464009a9b205a8976577400246b9cfc974043721acad3927d52c6310f3d277de&X-Tos-SignedHeaders=host',
        'object_name': 'prod-chat-kimi/kfs/1/2/2025-01-24/cu9p8tdf4398vu0atm9g',
        'file_id': 'kfs_2cu9p8tdf4398vu0atma0'
    }
    rsp = requests.post(url, json=data, headers=headers)
    s3obj = rsp.json()
    print(s3obj)
    url = s3obj['url']

    with open(path, 'rb') as of:
        files = {'file': of }
        rsp = requests.put(url, of, headers=headers)
        print(rsp.text, rsp.status_code)
    time.sleep(1)
    img = Image.open(path)
    data = {
        "name": os.path.basename(path),
        "object_name": s3obj['object_name'],
        "type": "image",
        "file_id": s3obj['file_id'],
        "meta": {
            "width": str(img.width),
            "height": str(img.height)
        }
    }
    print(data)
    url = 'https://kimi.moonshot.cn/api/file'
    rsp = requests.post(url, json=data, headers=headers)
    print(rsp.status_code, rsp.text)

    url = 'https://kimi.moonshot.cn/api/chat/cu9pang1gemcqa40qj3g/completion/stream'
    data = {
        "kimiplus_id": "kimi",
        "extend": {
            "sidebar": True
        },
        "model": "kimi",
        "use_research": False,
        "use_search": True,
        "messages": [
            {
                "role": "user",
                "content": "描述下这个图片，图片中是否出现了弹出窗口，窗口的关闭按钮在哪里(给出位置百分比)"
            }
        ],
        "refs": [
            s3obj['file_id']
        ],
        "history": [],
        "scene_labels": []
    }

    stream = False
    def getText(s):
        if ':' not in s:
            return ''
        s = s.split(':', 1)[1]
        obj = json.loads(s)
        if obj['event'] == 'cmpl':
            return obj['text']
        return ''
    rsp = requests.post(url, json=data, headers=headers, stream=stream)
    rsp.encoding = rsp.apparent_encoding
    txt = ''
    if stream:
        for chunk in rsp.iter_content(chunk_size=1024):
            txt += getText(chunk)
    else:
        for s in rsp.text.splitlines():
            txt += getText(s)
    print(txt)

def md5(txt):
    md5 = hashlib.md5()
    md5.update(txt.encode())
    return md5.hexdigest()

def list_get(session, lst, mp):
    out_mp = mp
    for s in lst:
        func = 0
        if not isinstance(s, str):
            s,func = s
        print(s)
        rsp = session.get(s)
        if func:
            func(rsp, out_mp)
    return out_mp

def get_csrf(rsp, mp):
    s = rsp.text
    if '_csrf' in s:
        m = re.search(r'name="_csrf".*?value="([^"]+)"', s)
        mp['_csrf'] = m.groups()[0]

def test_szlib():
    params = {'username':'370283198304194513', 'password':'Sztsg521', }
    params['password'] = md5('%s,%s'%(params['username'],params['password']))

    session = requests.session()
    lst = ['https://www.szlib.org.cn/',
    'https://www.szlib.org.cn/auth/oauth/authorize?show=qrcode&client_id=t1&grant_type=authorization_code&scope=app&redirect_uri=https://www.szlib.org.cn/MyLibrary/Reader-Access.jsp&response_type=code&eventsite=WWW-044005',
    ('https://szlib.org.cn/auth/userLogin#', get_csrf)]
    mp = list_get(session, lst, params)
    params['_csrf'] = mp['_csrf']
    print(params)
    rsp = session.post('https://www.szlib.org.cn/auth/login', data=params)
    recordno = session.cookies.get_dict().get('recordno', '')
    print(recordno)
    url = f'https://www.szlib.org.cn/MyLibrary/getloanlist.jsp?readerno={recordno}'
    rsp = session.get(url)
    s = rsp.text
    print(s)


if __name__ == '__main__':
    # main()
    # name = 'Screenshot_2023-01-01-20-01-24-189_top.niunaijun.blackboxa64'
    # test_json_image(name)
    # a = get_node_in_pos(990,305)
    # b = get_node_path('恭喜获得爆竹', a[0])
    # print(b, a[0].get('boundsInfo'))
    # AutojsElementSelect()
    #t1 = threading.Thread(target=udp_server)
    #t1.start()
##    runBottle()
    # loop_ftp()
    test_szlib()
    pass
